#include <jni.h>
#include <string>
#include "ohos_histreamer_demo_MainActivity.h"

#include <android/log.h>

#define LOG_TAG  "AppNdk"
#define ALOGD(...)  __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

#include <atomic>
#include "histreamer/hiplayer.h"

using namespace OHOS::Media;

std::string playerState{""};
struct JniAttacher{
public:
    JniAttacher(JavaVM *jvm)
    {
        javaVm_ = jvm;
        javaVm_->GetEnv((void **)&jniEnv_, JNI_VERSION_1_4);
        if (jniEnv_ == nullptr) {
            ALOGD("own by us");
            ownByUs_ = true;
            javaVm_->AttachCurrentThread(&jniEnv_, nullptr);
        }
    }
    JNIEnv* GetJEnv()
    {
        return jniEnv_;
    }
    ~JniAttacher()
    {
        if (ownByUs_) {
            javaVm_->DetachCurrentThread();
        }
    }

private:
    JavaVM *javaVm_;
    JNIEnv* jniEnv_;
    bool ownByUs_{false};
};

std::atomic<uint64_t> duration = 0;

std::shared_ptr<OHOS::Media::PlayerInterface> player;

extern "C"
JNIEXPORT void JNICALL Java_ohos_histreamer_demo_MainActivity_nativeInit(JNIEnv *env, jobject activity) {
    ALOGD("nativeInit called");
    player = OHOS::Media::CreateHiPlayer();
    player->Init();
}

extern "C"
JNIEXPORT void JNICALL Java_ohos_histreamer_demo_MainActivity_setDataSource(JNIEnv *env, jobject, jstring juri) {
    if (player) {
        std::string uri(env->GetStringUTFChars(juri, 0));
        OHOS::Media::Source source(uri);
        ALOGD("call setData;Source with uri: %s", uri.c_str());
        player->SetSource(source);
    }
}

extern "C"
JNIEXPORT void JNICALL Java_ohos_histreamer_demo_MainActivity_setLooping(JNIEnv *, jobject, jboolean looping)
{
    ALOGD("setLooping: %d", looping);
    if (player) {
        player->SetLoop(looping);
    }
}

extern "C"
JNIEXPORT void JNICALL Java_ohos_histreamer_demo_MainActivity_play(JNIEnv *env, jobject activity) {
    if (player->IsPlaying()) {
        player->Play();
    } else {
        duration = 0;
        player->Play();
    }
}

extern "C"
JNIEXPORT void JNICALL Java_ohos_histreamer_demo_MainActivity_nativeStop(JNIEnv *env, jobject activity) {
    player->Stop();
    duration = 0;
}

extern "C" JNIEXPORT void JNICALL
Java_ohos_histreamer_demo_MainActivity_pause(JNIEnv *env, jobject) {
    player->Pause();
}

extern "C" JNIEXPORT void JNICALL
Java_ohos_histreamer_demo_MainActivity_seekTo(JNIEnv *env, jobject, jlong time) {
    size_t mode = 0;
    auto error = player->Rewind(time, mode);
    ALOGD("getDuration returned %d", error);
}

extern "C" JNIEXPORT jlong JNICALL Java_ohos_histreamer_demo_MainActivity_getDuration (JNIEnv *env, jobject object)
{
    int64_t time = 0;
    auto error = player->GetDuration(time);
    if (error != 0) {
        ALOGD("get duration error");
    }
    if (time > 0) {
        duration = time;
    }
    return duration;
}

extern "C" JNIEXPORT jlong JNICALL Java_ohos_histreamer_demo_MainActivity_getCurrentTime (JNIEnv *env, jobject object)
{
    int64_t time = 0;
    auto error = player->GetCurrentPosition(time);
    return time;
}
